package com.zl.protocol;

import org.apache.commons.lang3.StringUtils;

/**
 * @author chenzy
 * @since 2024/9/2
 **/
public class MyException extends RuntimeException {
    public static final int CodeDefault = -66;
    public static final String MsgDefault = "系统异常";
    private Integer code;
    private Object data;


    public static void throwErrorFillInStackTrace(String msg){
        throw new MyException(CodeDefault,msg,true);
    }
    public static MyException throwError(String msg){
        throw  new MyException(msg);
    }
    public static MyException error(String message) {
        return new MyException(CodeDefault, message);
    }
    public static MyException errorFillTrace(String message) {
        return new MyException(CodeDefault, message,false);
    }

    private MyException() {
        this(CodeDefault, MsgDefault);
    }

    private MyException(String message) {
        this(CodeDefault, message);
    }

    private MyException(Integer code, String message) {
        this(code, message, null);
    }

    private MyException(Integer code, String message, boolean fillInStackTrace) {
        super(fillInStackTrace ? null : message, fillInStackTrace ? new RuntimeException(message) : null);
        this.code = code;
    }


    private MyException(Integer code, String message, Throwable e) {
        super(message, e);
        this.code = code;
    }

    public static <T> MyException error(Integer code, T data) {
        return error(code, MsgDefault, data);
    }

    public static <T> MyException error(Integer code, String msg, T data) {
        return new MyException(code, msg).setData(data);
    }

    public static MyException error(Integer code, String message) {
        return new MyException(code, message);
    }


    public static MyException error(Integer code, String message, Throwable throwable) {
        return new MyException(code, message, throwable);
    }

    public static <T> MyException error(Integer code, String message, Throwable throwable, T data) {
        return new MyException(code, message, throwable).setData(data);
    }


    public Object getData() {
        return data;
    }

    public MyException setData(Object data) {
        this.data = data;
        return this;
    }

    @Override
    public String getMessage() {
        var msg = super.getMessage();
        if (StringUtils.isBlank(msg)) {
            return MsgDefault;
        }
        return msg;
    }

    /**
     * 重写堆栈填充，大多数情况不需要填充错误堆栈信息，提高性能
     */
    @Override
    public MyException fillInStackTrace() {
        return this;
    }

    public Integer getCode() {
        return code;
    }
}
